
#include <BTreeWidget>

#include <BTreeItem>
#include "member_BTreeItem.h"
#include "member_BTreeWidget.h"

using namespace BWE;

#define member					(*(member_BTreeItem*)_ptr)
#define member_allocate()		_ptr = new member_BTreeItem(this)
#define member_release()		delete (member_BTreeItem*)_ptr

BTreeItem::BTreeItem(BTreeItem* parent)
{
	member_allocate();
	setParent(parent);
	member.dirtyTree();
}
BTreeItem::BTreeItem(const BString& text, BTreeItem* parent)
{
	member_allocate();
	setText(text);
	setParent(parent);
	member.dirtyTree();
}
BTreeItem::BTreeItem(BImage* image, const BString& text, BTreeItem* parent)
{
	member_allocate();
	setImage(image);
	setText(text);
	setParent(parent);
	member.dirtyTree();
}
BTreeItem::~BTreeItem()
{
	member_release();
}

void BTreeItem::setParent(BTreeItem* parent)
{
	if(member.parent != parent)
	{
		BHolder<BTreeItem> holder;
		if(member.parent)
		{
			member.dirtyTree();
			holder.hold(this);
			member.parent->removeChild(this);
		}
		if(parent)
		{
			parent->addChild(this);
			holder.drop();
			member.dirtyTree();
		}
	}
}
BTreeItem* BTreeItem::parent()
{
	return member.parent;
}
const BTreeItem* BTreeItem::parent() const
{
	return member.parent;
}

bool BTreeItem::addChild(BTreeItem* child)
{
	if (!child)
		return false;
	if (child == this)
		return false;
	if (member.children.contain(child))
		return true;
	item_member(child)->parent = this;
	item_member(child)->attach(member.tree);
	member.children.append(child);
	member.dirtyTree();
	return true;
}
BTreeItem* BTreeItem::addChild(const BString& text)
{
	BTreeItemHolder item = new BTreeItem(text);
	if (addChild(item))
		return item;
	return 0;
}
bool BTreeItem::removeChild(BTreeItem* child)
{
	if (!child)
		return false;
	if (child == this)
		return false;
	if (!member.children.contain(child))
		return false;
	if (member.tree)
	{
		tree_member(member.tree)->selectedItems.remove(child);
	}
	item_member(child)->parent = 0;
	item_member(child)->detach(member.tree);
	member.children.remove(child);
	member.dirtyTree();
	return true;
}
void BTreeItem::clearChildren()
{
	for (int i = 0; i < member.children.size(); i++)
	{
		BTreeItem* child = member.children[i];
		item_member(child)->parent = 0;
		item_member(child)->detach(member.tree);
	}
	member.children.clear();
	member.dirtyTree();
}

int BTreeItem::childCount() const
{
	return member.children.size();
}
BTreeItem* BTreeItem::child(int index)
{
	return member.children[index].ptr();
}
const BTreeItem* BTreeItem::child(int index) const
{
	return member.children[index].ptr();
}

BTreeItem* BTreeItem::child(const BString& text)
{
	for(int i = 0; i < member.children.size(); i++)
	{
		const BString& childText = member.children[i]->text();
		if (childText == text)
			return member.children[i].ptr();
	}
	return 0;
}
const BTreeItem* BTreeItem::child(const BString& text) const
{
	for(int i = 0; i < member.children.size(); i++)
	{
		if(member.children[i]->text() == text)
			return member.children[i].ptr();
	}
	return 0;
}

BTreeItem* BTreeItem::child(const BValue& value)
{
	for (int i = 0; i < member.children.size(); i++)
	{
		BTreeItem* child = member.children[i];
		if (child->value() == value)
			return child;
	}
	return 0;
}
const BTreeItem* BTreeItem::child(const BValue& value) const
{
	for (int i = 0; i < member.children.size(); i++)
	{
		BTreeItem* child = member.children[i];
		if (child->value() == value)
			return child;
	}
	return 0;
}

BTreeItem* BTreeItem::find(const BString& text)
{
	if (member.text == text)
		return this;
	for (int i = 0; i < member.children.size(); i++)
	{
		BTreeItem* child = member.children[i];
		BTreeItem* item = child->find(text);
		if (item)
			return item;
	}
	return 0;
}
const BTreeItem* BTreeItem::find(const BString& text) const
{
	if (member.text == text)
		return this;
	for (int i = 0; i < member.children.size(); i++)
	{
		const BTreeItem* child = member.children[i];
		const BTreeItem* item = child->find(text);
		if (item)
			return item;
	}
	return 0;
}

BTreeItem* BTreeItem::find(const BValue& value)
{
	if (member.value == value)
		return this;
	for (int i = 0; i < member.children.size(); i++)
	{
		BTreeItem* child = member.children[i];
		BTreeItem* item = child->find(value);
		if (item)
			return item;
	}
	return 0;
}
const BTreeItem* BTreeItem::find(const BValue& value) const
{
	if (member.value == value)
		return this;
	for (int i = 0; i < member.children.size(); i++)
	{
		const BTreeItem* child = member.children[i];
		const BTreeItem* item = child->find(value);
		if (item)
			return item;
	}
	return 0;
}

bool BTreeItem::containChild(const BTreeItem* item) const
{
	if (!item)
		return false;
	for (int i = 0; i < member.children.size(); i++)
	{
		if (member.children[i] == item)
			return true;
	}
	return false;
}
bool BTreeItem::containItem(const BTreeItem* item) const
{
	if (!item)
		return false;
	for (int i = 0; i < member.children.size(); i++)
	{
		BTreeItem* child = member.children[i];
		if (child == item)
			return true;
		bool result = child->containItem(item);
		if (result)
			return true;
	}
	return false;
}

void BTreeItem::expand()
{
	if (member.expanded != true)
	{
		member.expanded = true;
		member.dirtyTree();
	}
}
void BTreeItem::shrink()
{
	if (member.expanded != false)
	{
		member.expanded = false;
		member.dirtyTree();
	}
}
void BTreeItem::expandOrShrink()
{
	setExpanded(!member.expanded);
}

void BTreeItem::setExpanded(bool expanded)
{
	if (member.expanded)
		shrink();
	else
		expand();
}
bool BTreeItem::isExpanded() const
{
	return member.expanded;
}

void BTreeItem::setSelected(bool selected)
{
	if (member.tree && member.selected != selected)
	{
		member.tree->setItemSelected(this, selected);
	}
}
bool BTreeItem::isSelected() const
{
	return member.selected;
}

void BTreeItem::setText(const BString& text)
{
	if (member.text != text)
	{
		member.text = text;
		member.dirtyTree();
	}
}
const BString& BTreeItem::text() const
{
	return member.text;
}

void BTreeItem::setImage(BImage* image)
{
	if (member.image != image)
	{
		member.image = image;
		if (member.tree)
			member.tree->fresh();
	}
}
BImage* BTreeItem::image()
{
	return member.image;
}
const BImage* BTreeItem::image() const
{
	return member.image;
}

void BTreeItem::setWidget(BWidget* widget)
{
	if (member.widget != widget)
	{
		if (member.tree)
			member.tree->removeChild(member.widget);
		member.widget = widget;
		if (member.tree)
			member.tree->addChild(member.widget);
		if (member.widget)
			member.widget->setRect(member.rect);
	}
}
BWidget* BTreeItem::widget()
{
	return member.widget;
}
const BWidget* BTreeItem::widget() const
{
	return member.widget;
}

void BTreeItem::setValue(const BValue& value)
{
	if (member.value != value)
	{
		member.value = value;
	}
}
const BValue& BTreeItem::value() const
{
	return member.value;
}

int BTreeItem::level() const
{
	int level = 0;
	const BTreeItem* item = this->parent();
	while (item)
	{
		level++;
		item = item_member(item)->parent;
	}
	return level;
}

BString BTreeItem::path() const
{
	BString text = this->text();
	const BTreeItem* item = this->parent();
	while (item)
	{
		text.prepend('/');
		text.prepend(item->text());
		item = item->parent();
	}
	return text;
}
BRect BTreeItem::rect() const
{
	return member.rect;
}
BRect BTreeItem::contentRect() const
{
	return member.contentRect;
}



